<?php

namespace app\thirdPay\logic;

use app\data\util\HttpUtil;
use think\facade\Db;
use think\facade\Config;
use think\facade\Cache;

class LianLianPayServiceLogic
{
    protected $model = null;
    protected $llpay_config = [];

    public function __construct()
    {
        $this->llpay_config['oid_partner'] = '201408071000001539';
        //秘钥格式注意不能修改（左对齐，右边有回车符）
        $this->llpay_config['RSA_PRIVATE_KEY'] = '';
        //安全检验码，以数字和字母组成的字符
        $this->llpay_config['key'] = '201408071000001539_sahdisa_20141205';
        //版本号
        $this->llpay_config['version'] = '1.0';
        //防钓鱼ip
        $this->llpay_config['userreq_ip'] = '10.10.246.110';
        //证件类型
        $this->llpay_config['id_type'] = '0';
        //签名方式 不需修改
        $this->llpay_config['sign_type'] = strtoupper('RSA');
        //订单有效时间  分钟为单位，默认为10080分钟（7天） 
        $this->llpay_config['valid_order'] ="30";
        //字符编码格式 目前支持 gbk 或 utf-8
        $this->llpay_config['input_charset'] = strtolower('utf-8');
        //访问模式,根据自己的服务器是否支持ssl访问，若支持请选择https；若不支持请选择http
        $this->llpay_config['transport'] = 'http';
    }

    /**
     * 获取连连pay回款
     * @param $type
     * @return mixed
     */
    public function GetPaymentsLianLianPay($params=[])
    {
        $no_order = $params['no_order'] ?? '';
        $dt_order = $params['dt_order'] ?? '';
        $oid_paybill = $params['oid_paybill'] ?? '';
        $llpay_gateway_new = 'https://yintong.com.cn/queryapi/orderquery.htm';
        $parameter = array (
            "oid_partner" => trim($this->llpay_config['oid_partner']),
            "sign_type" => trim($this->llpay_config['sign_type']),
            "no_order" => $no_order,
            "dt_order" => $dt_order,
            "oid_paybill" => $oid_paybill
        );
        //建立请求
        $html_text = $this->buildRequestJSON($parameter,$llpay_gateway_new);
        dump($html_text);die;
        

        return json(DefaultResponse(200, true, '操作成功!'));
    }
    
	/**
	 * 建立请求，以模拟远程HTTP的POST请求方式构造并获取连连支付的处理结果
	 * @param $para_temp 请求参数数组
	 * @return 连连支付处理结果
	 */
	function buildRequestJSON($para_temp,$llpay_gateway_new) {
		$sResult = '';
		//待请求参数数组字符串
		$request_data = $this->buildRequestPara($para_temp);
		//远程获取数据
		$sResult = $this->getHttpResponseJSON($llpay_gateway_new, $request_data);
		return $sResult;
	}

    /**
	 * 生成要请求给连连支付的参数数组
	 * @param $para_temp 请求前的参数数组
	 * @return 要请求的参数数组
	 */
	function buildRequestPara($para_temp) {
		//除去待签名参数数组中的空值和签名参数
		$para_filter = $this->paraFilter($para_temp);
		//对待签名参数数组排序
        if (!empty($para_filter)) {
            $para_sort = $this->argSort($para_filter);
        }
		//生成签名结果
		$mysign = $this->buildRequestMysign($para_sort);
		//签名结果与签名方式加入请求提交参数组中
		$para_sort['sign'] = $mysign;
		$para_sort['sign_type'] = strtoupper(trim($this->llpay_config['sign_type']));
		foreach ($para_sort as $key => $value) {
			$para_sort[$key] = $value;
		}
		return $para_sort;
		//return urldecode(json_encode($para_sort));
	}

    /**
     * 除去数组中的空值和签名参数
     * @param $para 签名参数组
     * return 去掉空值与签名参数后的新签名参数组
     */
    function paraFilter($para) {
        $para_filter = array();
        foreach ($para as $key => $val) {
            if ($key == "sign" || $val == "") {
                continue;
            } else {
                $para_filter[$key] = $para[$key];
            }
        }
        return $para_filter;
    }

    /**
	 * 生成签名结果
	 * @param $para_sort 已排序要签名的数组
	 * return 签名结果字符串
	 */
	function buildRequestMysign($para_sort) {
		//把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
		$prestr = $this->createLinkstring($para_sort);
		$mysign = "";
		switch (strtoupper(trim($this->llpay_config['sign_type']))) {
			case "MD5" :
				$mysign = $this->md5Sign($prestr, $this->llpay_config['key']);
				break;
			case "RSA" :
				$mysign = $this->RsaSign($prestr, $this->llpay_config['RSA_PRIVATE_KEY']);
				break;
			default :
				$mysign = "";
		}
		file_put_contents("log.txt","签名:".$mysign."\n", FILE_APPEND);
		return $mysign;
	}

    /**
     * 签名字符串
     * @param $prestr 需要签名的字符串
     * @param $key 私钥
     * return 签名结果
     */
    function md5Sign($prestr, $key) {
        $logstr = $prestr."&key=************************";
        $prestr = $prestr ."&key=". $key;
        //file_put_contents("log.txt","签名原串:".$logstr."\n", FILE_APPEND);
        return md5($prestr);
    }

    
	/**RSA签名
	 * $data签名数据(需要先排序，然后拼接)
	 * 签名用商户私钥，必须是没有经过pkcs8转换的私钥
	 * 最后的签名，需要用base64编码
	 * return Sign签名
	 */
	
	function Rsasign($data,$priKey) {
        $res = openssl_get_privatekey($priKey);
        if (!$res) {
            die('Unable to load private key: ' . openssl_error_string());
        }
        
        $sign = '';
        if (!openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256)) { // Use a secure algorithm
            die('Unable to sign data: ' . openssl_error_string());
        }
		
		//base64编码
		$sign = base64_encode($sign);
		//file_put_contents("log.txt","签名原串:".$data."\n", FILE_APPEND);
		return $sign;
	}

    
    /**
     * 远程获取数据，POST模式
     * 注意：
     * @param $url 指定URL完整路径地址
     * @param $para 请求的数据
     * return 远程输出的数据
     */
    function getHttpResponseJSON($url, $para) {

        $json = json_encode($para);     
        $curl = curl_init($url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); //信任任何证书
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");                          
        curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, array(                 
            'Content-Type: application/json',
            'Content-Length: ' . strlen($json))         
        );
        $responseText = curl_exec($curl);
        file_put_contents("log.txt","返回值:".$responseText."\n", FILE_APPEND);  
        curl_close($curl);
        return $responseText;
    }
        
    /**
     * 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param $para 需要拼接的数组
     * return 拼接完成以后的字符串
     */
    function createLinkstring($para) {
        $arg  = "";
        foreach ($para as $key => $val) {
            $arg .= $key . "=" . $val . "&";
        }
        //去掉最后一个&字符
        $arg = substr($arg, 0, -1);
        //file_put_contents("log.txt","转义前:".$arg."\n", FILE_APPEND);
        //如果存在转义字符，那么去掉转义
        if (ini_get('magic_quotes_gpc')) {
            $arg = stripslashes($arg);
        }
        //file_put_contents("log.txt","转义后:".$arg."\n", FILE_APPEND);
        return $arg;
    }

    /**
     * 对数组排序
     * @param $para 排序前的数组
     * return 排序后的数组
     */
    function argSort($para) {
        ksort($para);
        reset($para);
        return $para;
    }

}

